Skip to content

feat: first-class lensing latent variable API in PyAutoLens - #534

Merged
Jammy2211 merged 1 commit into
mainfrom
feature/latent-module-autolens
May 23, 2026
Merged

feat: first-class lensing latent variable API in PyAutoLens#534
Jammy2211 merged 1 commit into
mainfrom
feature/latent-module-autolens

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

Summary

Adds the lensing latent-variable catalogue to PyAutoLens, building on the infrastructure PyAutoGalaxy #441 put in place. Five tracer-derived latents now live in autolens/analysis/latent.py:

  • total_lens_flux_mujy — integrated flux of the lens galaxy
  • total_lensed_source_flux_mujy — image-plane flux of the source after lensing
  • total_source_flux_mujy — source-plane intrinsic flux
  • magnification — image-plane / source-plane flux ratio
  • effective_einstein_radius — via LensCalc.einstein_radius_jit_from

AnalysisImaging overrides PyAutoFit's stubbed hooks (LATENT_KEYS @property + compute_latent_variables method) to dispatch through the registry. All five latents ship false in autolens/config/latent.yaml so the change is opt-in — existing fits remain unchanged. Users enable them in their workspace's config/latent.yaml and pass magzero via Analysis kwargs.

Closes #533. After this lands, sub-prompt #3 of the latent_refactor epic (euclid pipeline migration) can drop the bespoke LATENT_KEYS + compute_latent_variables in euclid_strong_lens_modeling_pipeline/util.py:306-490 and inherit the library catalogue (aperture-flux latents remain Euclid-specific by user direction).

API Changes

New public module autolens.analysis.latent exposing the five latent functions + LATENT_FUNCTIONS registry + latent_keys_enabled() reader. AnalysisImaging gains LATENT_KEYS @property and compute_latent_variables(parameters, model). New autolens/config/latent.yaml (all keys default false). Helpers ab_mag_via_flux_from / flux_mujy_via_ab_mag_from are imported from autogalaxy.imaging.model.latent (shipped in PyAutoGalaxy #441). No PyAutoFit changes. Latents take a generic fit argument and use APIs shared between FitImaging and FitInterferometer, so a future AnalysisInterferometer wiring can reuse the registry without duplication.

See full details below.

Test Plan

  • pytest test_autolens/analysis/test_latent.py -x -v — 17/17 pass
  • pytest test_autolens/ — 311/311 pass (no regression)
  • Workspace impact analysis follows after merge
  • End-to-end opt-in smoke (follow-up): enable a latent in workspace yaml, pass magzero, run autolens_workspace/scripts/imaging/start_here.py, inspect latent_summary.json
Full API Changes (for automation & release notes)

Added

  • autolens.analysis.latent — new module
  • autolens.analysis.latent.total_lens_flux_mujy(fit, magzero, xp=np) — total integrated lens-galaxy flux in muJy
  • autolens.analysis.latent.total_lensed_source_flux_mujy(fit, magzero, xp=np) — image-plane source flux after lensing
  • autolens.analysis.latent.total_source_flux_mujy(fit, magzero, xp=np) — source-plane intrinsic source flux
  • autolens.analysis.latent.magnification(fit, magzero, xp=np) — dimensionless flux ratio
  • autolens.analysis.latent.effective_einstein_radius(fit, magzero, xp=np) — via LensCalc
  • autolens.analysis.latent.LATENT_FUNCTIONS: Dict[str, Callable] — flat registry of name → function
  • autolens.analysis.latent.latent_keys_enabled(yaml_config=None) -> List[str] — config reader
  • autolens.AnalysisImaging.LATENT_KEYS — new `@property` overriding the inherited class-level `[]`
  • autolens.AnalysisImaging.compute_latent_variables(parameters, model) — overrides PyAutoFit's stub; returns tuple aligned to keys; raises NotImplementedError when LATENT_KEYS is empty
  • autolens/config/latent.yaml — new config file (5 keys, all false)

Changed Behaviour

  • No behaviour change for existing fits with the default config — all five latents ship false, so LATENT_KEYS is [], compute_latent_variables raises NotImplementedError, and autofit's existing except NotImplementedError: return None cleanly skips the latent pipeline. Matches today's behaviour.
  • When a latent is enabled and requires magzero (all four flux-derived latents), the latent computation raises ValueError loudly if magzero is not passed via AnalysisImaging(..., magzero=<value>). effective_einstein_radius and magnification do not require magzero.

Migration

None required. Existing code continues to work unchanged. To opt into a latent: set its key to true in <workspace>/config/latent.yaml and (for flux latents) pass magzero when constructing al.AnalysisImaging.

🤖 Generated with Claude Code

Add autolens/analysis/latent.py with a registry of five tracer-derived
latent variables — total_lens_flux_mujy, total_lensed_source_flux_mujy,
total_source_flux_mujy, magnification, effective_einstein_radius — plus
the latent_keys_enabled() config reader. autolens/config/latent.yaml
provides the user-toggle layer with all keys default `false` (same
regression reasoning as PyAutoGalaxy #441: compute_latent_samples runs
on every fit, and magzero-requiring latents would crash existing users
if enabled by default).

AnalysisImaging gains LATENT_KEYS @Property + compute_latent_variables
method, dispatching through the shared registry. NotImplementedError
short-circuit when no latents are enabled keeps autofit's existing
handler path clean.

Helpers ab_mag_via_flux_from / flux_mujy_via_ab_mag_from are imported
from PyAutoGalaxy (shipped in #441) — no duplication. The latent
functions take a generic `fit` argument and use fit.tracer /
fit.galaxy_image_dict / fit.dataset.grids.lp — APIs shared between
FitImaging and FitInterferometer — so the registry can be wired into
AnalysisInterferometer in a follow-up without code duplication.

Refs: #533
@Jammy2211 Jammy2211 added the pending-release PR queued for the next release build label May 23, 2026
@Jammy2211
Jammy2211 merged commit 3b7b2ff into main May 23, 2026
6 checks passed
@Jammy2211
Jammy2211 deleted the feature/latent-module-autolens branch May 23, 2026 16:22
@Jammy2211 Jammy2211 removed the pending-release PR queued for the next release build label Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: first-class lensing latent variable API in PyAutoLens

1 participant